Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add function selectors to psp22 trait #316

Conversation

chungquantin
Copy link
Collaborator

@chungquantin chungquantin commented Sep 30, 2024

Add function selectors to the PSP22 trait.

Below is a spec in the json metadata

{
    "constructors": [
      {
        "args": [
          {
            "label": "id",
            "type": {
              "displayName": [
                "TokenId"
              ],
              "type": 0
            }
          }
        ],
        "default": false,
        "docs": [
          "Instantiate the contract and wrap around an existing token.",
          "",
          "# Parameters",
          "* - `token` - The token."
        ],
        "label": "existing",
        "payable": true,
        "returnType": {
          "displayName": [
            "ink_primitives",
            "ConstructorResult"
          ],
          "type": 2
        },
        "selector": "0xda96b8d9"
      },
      {
        "args": [
          {
            "label": "id",
            "type": {
              "displayName": [
                "TokenId"
              ],
              "type": 0
            }
          },
          {
            "label": "min_balance",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          }
        ],
        "default": false,
        "docs": [
          "Instantiate the contract and create a new token. The token identifier will be stored",
          "in contract's storage.",
          "",
          "# Parameters",
          "* - `id` - The identifier of the token.",
          "* - `min_balance` - The minimum balance required for accounts holding this token."
        ],
        "label": "new",
        "payable": true,
        "returnType": {
          "displayName": [
            "ink_primitives",
            "ConstructorResult"
          ],
          "type": 2
        },
        "selector": "0x9bae9d5e"
      }
    ],
    "docs": [],
    "environment": {
      "accountId": {
        "displayName": [
          "AccountId"
        ],
        "type": 10
      },
      "balance": {
        "displayName": [
          "Balance"
        ],
        "type": 8
      },
      "blockNumber": {
        "displayName": [
          "BlockNumber"
        ],
        "type": 0
      },
      "chainExtension": {
        "displayName": [
          "ChainExtension"
        ],
        "type": 20
      },
      "hash": {
        "displayName": [
          "Hash"
        ],
        "type": 18
      },
      "maxEventTopics": 4,
      "staticBufferSize": 16384,
      "timestamp": {
        "displayName": [
          "Timestamp"
        ],
        "type": 19
      }
    },
    "events": [
      {
        "args": [
          {
            "docs": [
              "The owner providing the allowance."
            ],
            "indexed": true,
            "label": "owner",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "docs": [
              "The beneficiary of the allowance."
            ],
            "indexed": true,
            "label": "spender",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "docs": [
              "The new allowance amount."
            ],
            "indexed": false,
            "label": "value",
            "type": {
              "displayName": [
                "u128"
              ],
              "type": 8
            }
          }
        ],
        "docs": [
          "Event emitted when allowance by `owner` to `spender` changes."
        ],
        "label": "Approval",
        "module_path": "pop_api::v0::fungibles::events",
        "signature_topic": "0x25cdb6c93882e925abbfc9a8b7c85884b73c038c03a2492f238a5e5ba3fbff8c"
      },
      {
        "args": [
          {
            "docs": [
              "The source of the transfer. `None` when minting."
            ],
            "indexed": true,
            "label": "from",
            "type": {
              "displayName": [
                "Option"
              ],
              "type": 17
            }
          },
          {
            "docs": [
              "The recipient of the transfer. `None` when burning."
            ],
            "indexed": true,
            "label": "to",
            "type": {
              "displayName": [
                "Option"
              ],
              "type": 17
            }
          },
          {
            "docs": [
              "The amount transferred (or minted/burned)."
            ],
            "indexed": false,
            "label": "value",
            "type": {
              "displayName": [
                "u128"
              ],
              "type": 8
            }
          }
        ],
        "docs": [
          "Event emitted when transfer of tokens occurs."
        ],
        "label": "Transfer",
        "module_path": "pop_api::v0::fungibles::events",
        "signature_topic": "0x990df076cb1e9527aa102cd100c1481efe393eeabb5825f9af1f5e58221864de"
      },
      {
        "args": [
          {
            "docs": [
              "The token identifier."
            ],
            "indexed": true,
            "label": "id",
            "type": {
              "displayName": [
                "TokenId"
              ],
              "type": 0
            }
          },
          {
            "docs": [
              "The creator of the token."
            ],
            "indexed": true,
            "label": "creator",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "docs": [
              "The administrator of the token."
            ],
            "indexed": true,
            "label": "admin",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          }
        ],
        "docs": [
          "Event emitted when a token is created."
        ],
        "label": "Created",
        "module_path": "pop_api::v0::fungibles::events",
        "signature_topic": "0xb620b1bb1847ae00687a3e3afb8b212445e4f99886c5c997385e6851d50cefec"
      },
      {
        "args": [
          {
            "docs": [
              "The token."
            ],
            "indexed": true,
            "label": "token",
            "type": {
              "displayName": [
                "TokenId"
              ],
              "type": 0
            }
          }
        ],
        "docs": [
          "Event emitted when a token is in the process of being destroyed."
        ],
        "label": "DestroyStarted",
        "module_path": "pop_api::v0::fungibles::events",
        "signature_topic": "0x7a89feafd309935867fdcd4f299666c13d8d46ab2245ec0b5b708b12c9814c9b"
      },
      {
        "args": [
          {
            "docs": [
              "The token."
            ],
            "indexed": true,
            "label": "token",
            "type": {
              "displayName": [
                "TokenId"
              ],
              "type": 0
            }
          },
          {
            "docs": [
              "The name of the token."
            ],
            "indexed": true,
            "label": "name",
            "type": {
              "displayName": [
                "Vec"
              ],
              "type": 13
            }
          },
          {
            "docs": [
              "The symbol of the token."
            ],
            "indexed": true,
            "label": "symbol",
            "type": {
              "displayName": [
                "Vec"
              ],
              "type": 13
            }
          },
          {
            "docs": [
              "The decimals of the token."
            ],
            "indexed": false,
            "label": "decimals",
            "type": {
              "displayName": [
                "u8"
              ],
              "type": 12
            }
          }
        ],
        "docs": [
          "Event emitted when new metadata is set for a token."
        ],
        "label": "MetadataSet",
        "module_path": "pop_api::v0::fungibles::events",
        "signature_topic": "0x82bc140717b2c4c4f225b0aa8d9d1dd0eb296220b9e3977d283bacdc6e207f9e"
      },
      {
        "args": [
          {
            "docs": [
              "The token."
            ],
            "indexed": true,
            "label": "token",
            "type": {
              "displayName": [
                "TokenId"
              ],
              "type": 0
            }
          }
        ],
        "docs": [
          "Event emitted when metadata is cleared for a token."
        ],
        "label": "MetadataCleared",
        "module_path": "pop_api::v0::fungibles::events",
        "signature_topic": "0x0f063fd8e05e73ac7f2a378e09f2c4e0e00d071bc981c9c991a0d69f23e6ee27"
      }
    ],
    "lang_error": {
      "displayName": [
        "ink",
        "LangError"
      ],
      "type": 7
    },
    "messages": [
      {
        "args": [],
        "default": false,
        "docs": [
          " Returns the total token supply."
        ],
+       "label": "Psp22::total_supply",
        "mutates": false,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 9
        },
+        "selector": "0x162df8c2"
      },
      {
        "args": [
          {
            "label": "owner",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          }
        ],
        "default": false,
        "docs": [
          " Returns the account balance for the specified `owner`.",
          "",
          " # Parameters",
          " - `owner` - The account whose balance is being queried."
        ],
+        "label": "Psp22::balance_of",
        "mutates": false,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 9
        },
+        "selector": "0x6568382f"
      },
      {
        "args": [
          {
            "label": "owner",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "spender",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          }
        ],
        "default": false,
        "docs": [
          " Returns the allowance for a `spender` approved by an `owner`.",
          "",
          " # Parameters",
          " - `owner` - The account that owns the tokens.",
          " - `spender` - The account that is allowed to spend the tokens."
        ],
+        "label": "Psp22::allowance",
        "mutates": false,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 9
        },
+        "selector": "0x4d47d921"
      },
      {
        "args": [
          {
            "label": "to",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "value",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          },
          {
            "label": "_data",
            "type": {
              "displayName": [
                "Vec"
              ],
              "type": 13
            }
          }
        ],
        "default": false,
        "docs": [
          " Transfers `value` amount of tokens from the caller's account to account `to`",
          " with additional `data` in unspecified format.",
          "",
          " # Parameters",
          " - `to` - The recipient account.",
          " - `value` - The number of tokens to transfer.",
          " - `data` - Additional data in unspecified format."
        ],
+        "label": "Psp22::transfer",
        "mutates": true,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 2
        },
+        "selector": "0xdb20f9f5"
      },
      {
        "args": [
          {
            "label": "from",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "to",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "value",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          },
          {
            "label": "_data",
            "type": {
              "displayName": [
                "Vec"
              ],
              "type": 13
            }
          }
        ],
        "default": false,
        "docs": [
          " Transfers `value` tokens on behalf of `from` to the account `to`",
          " with additional `data` in unspecified format.",
          "",
          " # Parameters",
          " - `from` - The account from which the token balance will be withdrawn.",
          " - `to` - The recipient account.",
          " - `value` - The number of tokens to transfer.",
          " - `data` - Additional data with unspecified format."
        ],
+      "label": "Psp22::transfer_from",
        "mutates": true,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 2
        },
+       "selector": "0x54b3c76e"
      },
      {
        "args": [
          {
            "label": "spender",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "value",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          }
        ],
        "default": false,
        "docs": [
          " Approves `spender` to spend `value` amount of tokens on behalf of the caller.",
          "",
          " Successive calls of this method overwrite previous values.",
          "",
          " # Parameters",
          " - `spender` - The account that is allowed to spend the tokens.",
          " - `value` - The number of tokens to approve."
        ],
+       "label": "Psp22::approve",
        "mutates": true,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 2
        },
+        "selector": "0xb20f1bbd"
      },
      {
        "args": [
          {
            "label": "spender",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "value",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          }
        ],
        "default": false,
        "docs": [
          " Increases the allowance of `spender` by `value` amount of tokens.",
          "",
          " # Parameters",
          " - `spender` - The account that is allowed to spend the tokens.",
          " - `value` - The number of tokens to increase the allowance by."
        ],
+       "label": "Psp22::increase_allowance",
        "mutates": true,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 2
        },
+        "selector": "0x96d6b57a"
      },
      {
        "args": [
          {
            "label": "spender",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "value",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          }
        ],
        "default": false,
        "docs": [
          " Decreases the allowance of `spender` by `value` amount of tokens.",
          "",
          " # Parameters",
          " - `spender` - The account that is allowed to spend the tokens.",
          " - `value` - The number of tokens to decrease the allowance by."
        ],
+       "label": "Psp22::decrease_allowance",
        "mutates": true,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 2
        },
+        "selector": "0xfecb57d5"
      },
      {
        "args": [],
        "default": false,
        "docs": [
          " Returns the token name."
        ],
+        "label": "Psp22Metadata::token_name",
        "mutates": false,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 14
        },
+        "selector": "0x3d261bd4"
      },
      {
        "args": [],
        "default": false,
        "docs": [
          " Returns the token symbol."
        ],
+        "label": "Psp22Metadata::token_symbol",
        "mutates": false,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 14
        },
+        "selector": "0x34205be5"
      },
      {
        "args": [],
        "default": false,
        "docs": [
          " Returns the token decimals."
        ],
+       "label": "Psp22Metadata::token_decimals",
        "mutates": false,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 16
        },
+       "selector": "0x7271b782"
      },
      {
        "args": [
          {
            "label": "account",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "value",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          }
        ],
        "default": false,
        "docs": [
          " Creates `value` amount of tokens and assigns them to `account`, increasing the total",
          " supply.",
          "",
          " # Parameters",
          " - `account` - The account to be credited with the created tokens.",
          " - `value` - The number of tokens to mint."
        ],
+        "label": "Psp22Mintable::mint",
        "mutates": true,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 2
        },
+       "selector": "0xfc3c75d4"
      },
      {
        "args": [
          {
            "label": "account",
            "type": {
              "displayName": [
                "AccountId"
              ],
              "type": 10
            }
          },
          {
            "label": "value",
            "type": {
              "displayName": [
                "Balance"
              ],
              "type": 8
            }
          }
        ],
        "default": false,
        "docs": [
          " Destroys `value` amount of tokens from `account`, reducing the total supply.",
          "",
          " # Parameters",
          " - `account` - The account from which the tokens will be destroyed.",
          " - `value` - The number of tokens to destroy."
        ],
+        "label": "Psp22Burnable::burn",
        "mutates": true,
        "payable": false,
        "returnType": {
          "displayName": [
            "ink",
            "MessageResult"
          ],
          "type": 2
        },
+       "selector": "0x7a9da510"
      }
    ]
  },

@codecov-commenter
Copy link

codecov-commenter commented Sep 30, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Please upload report for BASE (chungquantin/feat-psp22_example@1857ea6). Learn more about missing BASE report.

@@                        Coverage Diff                         @@
##             chungquantin/feat-psp22_example     #316   +/-   ##
==================================================================
  Coverage                                   ?   51.44%           
==================================================================
  Files                                      ?       48           
  Lines                                      ?     4893           
  Branches                                   ?     4893           
==================================================================
  Hits                                       ?     2517           
  Misses                                     ?     2327           
  Partials                                   ?       49           

Copy link
Collaborator

@Daanvdplas Daanvdplas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious to hear why all the docs? Personally I think adding the selector is enough and a reference to the psp22 standard in the readme will be enough.

@chungquantin chungquantin self-assigned this Oct 1, 2024
@chungquantin
Copy link
Collaborator Author

@Daanvdplas Removed doc but still keep the reference section. What's your thoughts?

@Daanvdplas
Copy link
Collaborator

Still think it is too much. The link all reference the same URL. This only increases the maintenance and development work for all future standards that we will add.

Copy link
Collaborator

@evilrobot-01 evilrobot-01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are mistakes in the selector attributes for mint and burn.

Also, there is no evidence that applying these to the trait will ensure that it will be correctly set when used on a contract. Is it possible to add the relevant traits to a contract, ideally in this PR if possible but only if an existing contract exists within the codebase that is suitable, and then attach the resulting contract metadata/ABI as a comment as proof?

If not, just the ABI from some non-versioned contolled contract is fine. The only justification is confirming the assumption that a contract implementing the trait will have standards compliant messages within its ABI.

pop-api/src/v0/fungibles/traits.rs Outdated Show resolved Hide resolved
pop-api/src/v0/fungibles/traits.rs Show resolved Hide resolved
pop-api/src/v0/fungibles/traits.rs Show resolved Hide resolved
@@ -101,10 +106,13 @@ pub trait Psp22Metadata {
pub trait Psp22Mintable {
/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply.
///
/// The selector for this message is `0x7a9da510` (first 4 bytes of
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually verified to be correct.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -113,9 +121,12 @@ pub trait Psp22Mintable {
pub trait Psp22Burnable {
/// Destroys `value` amount of tokens from `account`, reducing the total supply.
///
/// The selector for this message is `0xfc3c75d4` (first 4 bytes of
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually verified to be correct.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chungquantin chungquantin changed the base branch from main to chungquantin/feat-psp22_example October 2, 2024 11:59
Copy link
Collaborator

@Daanvdplas Daanvdplas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job! LGTM!

Copy link
Collaborator

@evilrobot-01 evilrobot-01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thank you so much!

@chungquantin chungquantin merged commit eee369a into chungquantin/feat-psp22_example Oct 3, 2024
14 of 15 checks passed
@chungquantin chungquantin deleted the chungquantin/feat-psp22_func_selector branch October 3, 2024 02:51
@chungquantin chungquantin restored the chungquantin/feat-psp22_func_selector branch October 3, 2024 05:52
chungquantin added a commit that referenced this pull request Oct 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: fungible example contract function selector
4 participants